package com.leetcode.multithreading.licm;

/**
 * @description: 发令枪，考察 wait 配合 notifyall
 * @author: licm
 * @create: 2021-07-26 15:57
 **/
public class Gun {
    private int ammo = 0;

    private synchronized void put() {
        while (ammo >= 20) {
            try {
                wait();
                System.out.println("子弹满了 20颗  " + ammo);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        ammo++;
        System.out.println("子弹增加一个" + Thread.currentThread().getName() + ' ' + ammo);
        notifyAll();
    }

    private synchronized void get() {
        while (ammo <= 0) {
            try {
                wait();
                System.out.println("子弹没了" + ammo);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
        ammo--;
        System.out.println("子弹减少一个" + Thread.currentThread().getName() + ' ' + ammo);
        notifyAll();
    }

    static class Consumer implements Runnable {
        private Gun gun;

        public Consumer(Gun gun) {
            this.gun = gun;
        }

        @Override
        public void run() {
            while (true) {
                gun.get();
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    static class Product implements Runnable {
        private Gun gun;

        public Product(Gun gun) {
            this.gun = gun;
        }

        @Override
        public void run() {
            while (true) {
                gun.put();
                try {
                    Thread.sleep(1);
                } catch (InterruptedException e) {
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
        Gun gun = new Gun();

        for (int i = 0; i < 10; i++) {
            new Thread(new Product(gun)).start();
        }


        for (int i = 0; i < 10; i++) {
            new Thread(new Consumer(gun)).start();
        }
    }
}
